﻿' ******************************************************************************
' ** 
' **  Yahoo! Managed
' **  Written by Marius Häusler 2011
' **  It would be pleasant, if you contact me when you are using this code.
' **  Contact: YahooFinanceManaged@gmail.com
' **  Project Home: http://code.google.com/p/yahoo-finance-managed/
' **  
' ******************************************************************************
' **  
' **  Copyright 2011 Marius Häusler
' **  
' **  Licensed under the Apache License, Version 2.0 (the "License");
' **  you may not use this file except in compliance with the License.
' **  You may obtain a copy of the License at
' **  
' **    http://www.apache.org/licenses/LICENSE-2.0
' **  
' **  Unless required by applicable law or agreed to in writing, software
' **  distributed under the License is distributed on an "AS IS" BASIS,
' **  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
' **  See the License for the specific language governing permissions and
' **  limitations under the License.
' ** 
' ******************************************************************************


Namespace YahooManaged.Finance.Support

    ''' <summary>
    ''' Class for downloading exchange data
    ''' </summary>
    ''' <remarks></remarks>
    Public Class ExchangeRateDownload


        ''' <summary>
        ''' Raises if an asynchronous download of exchange rates completes
        ''' </summary>
        ''' <param name="sender">The event raising object</param>
        ''' <param name="ea">The event args of the asynchronous download</param>
        ''' <remarks></remarks>
        Public Event AsyncRateDownloadCompleted(ByVal sender As Object, ByVal ea As ExchangeRateDownloadCompletedEventArgs)

        Friend mFinanceHelper As New FinanceHelper

        Private WithEvents mQuotesBaseDownload As New API.QuotesBaseDownload
        Private WithEvents mHistQuotesDownload As New API.HistQuotesDownload

        Public Property Proxy As Net.IWebProxy
            Get
                Return mQuotesBaseDownload.Proxy
            End Get
            Set(ByVal value As Net.IWebProxy)
                mQuotesBaseDownload.Proxy = value
                mHistQuotesDownload.Proxy = value
            End Set
        End Property

        Public Function CancelAsyncAll() As Boolean
            Return mQuotesBaseDownload.CancelAsyncAll() And mHistQuotesDownload.CancelAsyncAll
        End Function


        ''' <summary>
        ''' Downloads a list of actual currency exchange rates
        ''' </summary>
        ''' <param name="currencies">List of all currency-pairs</param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function Download(ByVal currencies() As YCurrencyID) As ExchangeRateResponse
            If currencies Is Nothing Then Throw New ArgumentNullException("currencies", "The passed currencies have no values.")
            Return Me.ToResponse(mQuotesBaseDownload.Download(mFinanceHelper.IIDsToStrings(currencies)))
        End Function
        ''' <summary>
        ''' Downloads a list of historical currency exchange rates
        ''' </summary>
        ''' <param name="currencies"></param>
        ''' <param name="tradeDate"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function Download(ByVal currencies() As YCurrencyID, ByVal tradeDate As DateTime) As ExchangeRateResponse
            If currencies Is Nothing Then Throw New ArgumentNullException("currencies", "The passed currencies have no values.")
            Return Me.ToResponse(mHistQuotesDownload.Download(mFinanceHelper.IIDsToStrings(currencies), tradeDate, tradeDate, HistQuotesInterval.Daily))
        End Function

        ''' <summary>
        ''' Starts an asynchronous download of actual currency exchange rates
        ''' </summary>
        ''' <param name="currencies">List of all currency-pairs</param>
        ''' <param name="userArgs">Individual user argument</param>
        ''' <remarks></remarks>
        Public Overloads Sub DownloadAsync(ByVal currencies() As YCurrencyID, Optional ByVal userArgs As Object = Nothing)
            If currencies Is Nothing Then : Throw New ArgumentNullException("currencies", "The passed currencies have no values.")
            Else
                Dim args As New AsyncDownloadArgs(userArgs, currencies)
                mQuotesBaseDownload.DownloadAsync(mFinanceHelper.IIDsToStrings(args.Currencies), args)
            End If
        End Sub
        ''' <summary>
        '''  Starts an asynchronous download of historic currency exchange rates
        ''' </summary>
        ''' <param name="currencies">List of all currency-pairs</param>
        ''' <param name="tradeDate">The trade date of exchange rates</param>
        ''' <param name="userArgs">Individual user argument</param>
        ''' <remarks></remarks>
        Public Overloads Sub DownloadAsync(ByVal currencies() As YCurrencyID, ByVal tradeDate As DateTime, Optional ByVal userArgs As Object = Nothing)
            If currencies Is Nothing Then : Throw New ArgumentNullException("currencies", "The passed currencies have no values.")
            Else
                Dim args As New AsyncDownloadArgs(userArgs, currencies)
                mHistQuotesDownload.DownloadAsync(mFinanceHelper.IIDsToStrings(args.Currencies), tradeDate, tradeDate, HistQuotesInterval.Daily, args)
            End If
        End Sub


        ''' <summary>
        ''' Default constructor
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub New()
        End Sub

        Private Sub DownloadAsync_Completed(ByVal sender As Base.Download, ByVal e As API.QuotesBaseDownloadCompletedEventArgs) Handles mQuotesBaseDownload.AsyncDownloadCompleted
            Dim dlArgs As AsyncDownloadArgs = DirectCast(e.UserArgs, AsyncDownloadArgs)
            RaiseEvent AsyncRateDownloadCompleted(Me, New ExchangeRateDownloadCompletedEventArgs(dlArgs.UserArgs, Me.ToResponse(e.Response), dlArgs.Currencies))
        End Sub
        Private Sub DownloadAsync_Completed(ByVal sender As Base.Download, ByVal e As API.HistQuotesDownloadCompletedEventArgs) Handles mHistQuotesDownload.AsyncDownloadCompleted
            Dim dlArgs As AsyncDownloadArgs = DirectCast(e.UserArgs, AsyncDownloadArgs)
            RaiseEvent AsyncRateDownloadCompleted(Me, New ExchangeRateDownloadCompletedEventArgs(dlArgs.UserArgs, Me.ToResponse(e.Response), dlArgs.Currencies))
        End Sub

        Private Function ToResponse(ByVal resp As API.QuotesBaseResponse) As ExchangeRateResponse
            Dim lst As New List(Of ExchangeRateData)
            If resp.Result IsNot Nothing Then
                For Each q As QuoteBaseData In resp.Result
                    Dim cur As YCurrencyID = mFinanceHelper.YCurrencyIDFromString(q.ID)
                    If cur IsNot Nothing Then lst.Add(New ExchangeRateData(cur.BaseCurrency, cur.DepCurrency, q))
                Next
            End If
            Return New ExchangeRateResponse(resp.Connection, lst.ToArray)
        End Function
        Private Function ToResponse(ByVal resp As API.HistQuotesResponse) As ExchangeRateResponse
            Dim lst As New List(Of ExchangeRateData)
            If resp.Result IsNot Nothing Then
                For Each hqc As HistQuotesDataChain In resp.Result
                    If hqc.Count > 0 Then
                        Dim cur As YCurrencyID = mFinanceHelper.YCurrencyIDFromString(hqc.ID)
                        If cur IsNot Nothing Then
                            Dim q As New QuoteBaseData(hqc.ID)
                            With hqc(0)
                                q.Change = .Close - .PreviousClose
                                q.Open = .Open
                                q.LastTradePriceOnly = .Close
                                q.LastTradeDate = .TradingDate
                                q.DaysHigh = .High
                                q.DaysLow = .Low
                                q.Volume = .Volume
                            End With
                            lst.Add(New ExchangeRateData(cur.BaseCurrency, cur.DepCurrency, q))
                        End If
                    End If
                Next
            End If
            Return New ExchangeRateResponse(resp.Connection, lst.ToArray)
        End Function

        Private Class AsyncDownloadArgs
            Inherits Base.DownloadEventArgs
            Public Currencies() As YCurrencyID
            Public Sub New(ByVal userArgs As Object, ByVal curs() As YCurrencyID)
                MyBase.New(userArgs)
                Me.Currencies = curs
            End Sub
        End Class



    End Class

    ''' <summary>
    ''' Stores the received exchange rate informations of an asynchronous download
    ''' </summary>
    ''' <remarks></remarks>
    Public Class ExchangeRateDownloadCompletedEventArgs
        Inherits Base.DownloadCompletedEventArgs

        Private mCurrencies() As YCurrencyID

        Public ReadOnly Property Currencies() As YCurrencyID()
            Get
                Return mCurrencies
            End Get
        End Property
        Public Overloads ReadOnly Property Response() As ExchangeRateResponse
            Get
                Return DirectCast(MyBase.Response, ExchangeRateResponse)
            End Get
        End Property

        Friend Sub New(ByVal userArgs As Object, ByVal resp As ExchangeRateResponse, ByVal curs() As YCurrencyID)
            MyBase.New(userArgs, resp)
            mCurrencies = curs
        End Sub

    End Class

    Public Class ExchangeRateResponse
        Inherits Base.Response

        Public Overloads ReadOnly Property Result() As ExchangeRateData()
            Get
                Return TryCast(MyBase.Result, ExchangeRateData())
            End Get
        End Property

        Friend Sub New(ByVal info As Base.ConnectionInfo, ByVal result As ExchangeRateData())
            MyBase.New(info, result)
        End Sub

    End Class

End Namespace